package com.web.exiaodao.business.service.impl;

import com.web.exiaodao.business.entity.FanliOrder;
import com.web.exiaodao.business.repository.FanliOrderRepository;
import com.web.exiaodao.business.service.FanliOrderService;
import com.web.exiaodao.remote.vo.FanliOrderVo;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.excelUtil.ExcelColumn;
import com.web.webstart.base.excelUtil.ExcelHead;
import com.web.webstart.base.excelUtil.ExcelHelper;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.service.impl.BaseService;
import com.web.webstart.base.util.SqlResultUtil;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.DynamicSpecifications;
import com.web.webstart.base.util.jpa.MyPage;
import com.web.webstart.base.util.jpa.SearchFilter;
import com.web.webstart.base.util.jpa.SearchFilter.Operator;
import com.web.webstart.base.util.jpa.WebUitl;
import com.web.webstart.base.util.result.XaResult;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("FanliOrderService")
@Transactional(readOnly = false)
public class FanliOrderServiceImpl extends BaseService<FanliOrder> implements FanliOrderService {

    private static final Logger LOGGER = Logger.getLogger(FanliOrderServiceImpl.class);

    @Autowired
    private FanliOrderRepository fanliOrderRepository;

    /**
     * 查询单条FanliOrder信息
     * //@param tId
     *
     * @return 返回单个FanliOrder对象
     * @throws BusinessException
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public XaResult<FanliOrder> findOne(Long modelId) throws BusinessException {
        FanliOrder obj = new FanliOrder();
        if (modelId != 0) {
            obj = fanliOrderRepository.findByIdAndStatusNot(modelId, XaConstant.Status.delete);
        }
        XaResult<FanliOrder> xr = new XaResult<FanliOrder>();
        if (XaUtil.isNotEmpty(obj)) {
            xr.setObject(obj);
            LOGGER.info("后台----->查询单个实体----->FanliOrder");
        } else {
            xr.error(XaConstant.Message.object_not_find);
            LOGGER.info(XaConstant.Message.object_not_find);
        }
        return xr;
    }

    /**
     * 分页查询状态非status的FanliOrder数据
     *
     * @param status
     * @param filterParams
     * @param pageable
     * @return 返回对象FanliOrder集合
     * @throws BusinessException
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public XaResult<Page<FanliOrder>> findListNEStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
        Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
        if (status == null) {// 默认显示非删除的所有数据
            status = XaConstant.Status.delete;
        }
        filters.put("status", new SearchFilter("status", Operator.NE, status));
        Page<FanliOrder> page = fanliOrderRepository.findAll(DynamicSpecifications
                .bySearchFilter(filters.values(), FanliOrder.class), pageable);
        XaResult<Page<FanliOrder>> xr = new XaResult<Page<FanliOrder>>();
        xr.setObject(page);
        LOGGER.info("后台----->分页查询实体集合（状态不等于）----->FanliOrder");
        return xr;
    }

    /**
     * 分页查询状态status的FanliOrder数据
     *
     * @param status
     * @param filterParams
     * @param pageable
     * @return 返回对象FanliOrder集合
     * @throws BusinessException
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public XaResult<Page<FanliOrder>> findListEQStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
        Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
        if (status == null) {// 默认显示正常数据
            status = XaConstant.Status.valid;
        }
        filters.put("status", new SearchFilter("status", Operator.EQ, status));
        Page<FanliOrder> page = fanliOrderRepository.findAll(DynamicSpecifications
                .bySearchFilter(filters.values(), FanliOrder.class), pageable);
        XaResult<Page<FanliOrder>> xr = new XaResult<Page<FanliOrder>>();
        xr.setObject(page);
        LOGGER.info("后台----->分页查询实体集合（状态等于）----->FanliOrder");
        return xr;
    }

    /**
     * 保存FanliOrder信息
     *
     * @param model
     * @return
     * @throws BusinessException
     */
    @Transactional(rollbackFor = Exception.class)
    public XaResult<FanliOrder> saveOrUpdate(FanliOrder model) throws BusinessException {
        FanliOrder obj = null;
        if (XaUtil.isNotEmpty(model.getId())) {
            obj = fanliOrderRepository.findOne(model.getId());
        } else {
            obj = new FanliOrder();
        }
        obj.setCreateUser(XaUtil.isNotEmpty(model.getCreateUser()) ? model.getCreateUser() : obj.getCreateUser());
        obj.setBusId(XaUtil.isNotEmpty(model.getBusId()) ? model.getBusId() : obj.getBusId());
        obj.setCreatOrderTime(XaUtil.isNotEmpty(model.getCreatOrderTime()) ? model.getCreatOrderTime() : obj.getCreatOrderTime());
        obj.setOrderMoney(XaUtil.isNotEmpty(model.getOrderMoney()) ? model.getOrderMoney() : obj.getOrderMoney());
        obj.setOrderNo(XaUtil.isNotEmpty(model.getOrderNo()) ? model.getOrderNo() : obj.getOrderNo());
        obj.setShopName(XaUtil.isNotEmpty(model.getShopName()) ? model.getShopName() : obj.getShopName());
        obj.setShopBrief(XaUtil.isNotEmpty(model.getShopBrief()) ? model.getShopBrief() : obj.getShopBrief());
        obj.setShopImg(XaUtil.isNotEmpty(model.getShopImg()) ? model.getShopImg() : obj.getShopImg());
        obj.setFanliMoney(XaUtil.isNotEmpty(model.getFanliMoney()) ? model.getFanliMoney() : obj.getFanliMoney());
        obj.setFaliTime(XaUtil.isNotEmpty(model.getFaliTime()) ? model.getFaliTime() : obj.getFaliTime());
        obj.setFaliOrderStatus(XaUtil.isNotEmpty(model.getFaliOrderStatus()) ? model.getFaliOrderStatus() : obj.getFaliOrderStatus());
        obj.setUserId(XaUtil.isNotEmpty(model.getUserId()) ? model.getUserId() : obj.getUserId());
        obj.setPlatformFanliMoney(XaUtil.isNotEmpty(model.getPlatformFanliMoney()) ? model.getPlatformFanliMoney() : obj.getPlatformFanliMoney());
        obj = fanliOrderRepository.save(obj);
        XaResult<FanliOrder> xr = new XaResult<FanliOrder>();
        xr.setObject(obj);
        LOGGER.info("后台新增或编辑数据成功！");
        return xr;
    }

    /**
     * 修改FanliOrder状态，可一次修改多条   3删除  -1锁定  1正常
     * //@param userId
     *
     * @param modelIds
     * @param status
     * @return 返回FanliOrder对象
     * @throws BusinessException
     */
    @Transactional(rollbackFor = Exception.class)
    public XaResult<FanliOrder> multiOperate(
            String modelIds, Integer status) throws BusinessException {
        XaResult<FanliOrder> xr = new XaResult<FanliOrder>();
        if (status == null) {
            status = XaConstant.Status.delete;
        }
        if (modelIds != null) {
            String[] ids = modelIds.split(",");
            for (String id : ids) {
                FanliOrder obj = fanliOrderRepository.findByIdAndStatusNot(Long.parseLong(id), status);
                if (XaUtil.isNotEmpty(obj)) {
                    obj.setStatus(status);
                    obj = fanliOrderRepository.save(obj);
                }
            }
        }
        LOGGER.info("批量修改数据状态成功！");
        return xr;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public void exportdata(Map<String, Object> filterParams,
                           HttpServletResponse response, String modelIds)
            throws BusinessException {
        Pageable pageable = WebUitl.buildPageRequest(0, Integer.MAX_VALUE, "[{property:'createTime',direction:'DESC'}]");
        Page<FanliOrder> page = this.findListNEStatusByFilter(XaConstant.Status.delete, filterParams, pageable).getObject();
        List<FanliOrder> orderVoList = new ArrayList<>();
        if (XaUtil.isNotEmpty(page) && XaUtil.isNotEmpty(page.getContent())) {
            orderVoList.addAll(page.getContent());
        }

        //excel结构
        List<ExcelColumn> excelColumns = new ArrayList<ExcelColumn>();
        excelColumns.add(new ExcelColumn(0, "id", "订单编号", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(1, "orderNo", "订单号", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(2, "busId", "商家编号", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(3, "creatOrderTime", "下单时间", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(4, "orderMoney", "订单金额", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(5, "shopName", "商品名称", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(6, "fanliMoney", "预计返利金额", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(7, "faliTime", "预计返利日期", Cell.CELL_TYPE_STRING));
        excelColumns.add(new ExcelColumn(8, "faliOrderStatus", "返利订单状态", Cell.CELL_TYPE_STRING));

        // 需要特殊转换的单元 map的可以必须好实体的类型一致
        /**
         * {@link JConstant.Order_CommentType}
         */
        Map<String, Map> excelColumnsConvertMap = new HashMap<>();
        Map<String, String> isReceive = new HashMap<>();
        isReceive.put("0", "即将可以（即将可以用返利）");
        isReceive.put("1", "已经返利");
        isReceive.put("2", "无返利");
        excelColumnsConvertMap.put("faliOrderStatus", isReceive);

        //设置头部
        ExcelHead head = new ExcelHead();
        head.setRowCount(1); // 模板中头部所占行数
        head.setColumns(excelColumns);  // 列的定义
        head.setColumnsConvertMap(excelColumnsConvertMap); // 列的转换
        //执行导出,第一个null是response参数，用来输出到浏览器，第二个null是要导出的数据集合
        ExcelHelper.getInstanse().exportExcelFile(response, head, orderVoList);

    }


    @Override
    public XaResult<Page<FanliOrderVo.FanliStatistics>> findStatisticsByYearFilter(Long busId, String year, Pageable pageable) throws BusinessException {
        XaResult<Page<FanliOrderVo.FanliStatistics>> xr = new XaResult<>();
        int begin = pageable.getPageNumber()*pageable.getPageSize();
        int count = pageable.getPageSize();
        String sqlWhere = "";
        if (XaUtil.isNotEmpty(busId) && busId > 0) {
            sqlWhere = " AND bus_id = " + busId + " ";
        }
        if (XaUtil.isNotEmpty(year)) {
            sqlWhere = " AND left(fali_time,4) = '" + year + "' ";
        }
        //列表查询语句
        String sql = "  SELECT bus_id,buss.business_name, left(fali_time, 10) ,count(platform_fanli_money) as monthMoney FROM tb_xa_fanliorder orders LEFT JOIN tb_xa_fanlibusiness buss ON orders.bus_id = buss.id\n" +
                "        WHERE 1 = 1 AND buss.status <> 3 " + sqlWhere + " GROUP BY left(fali_time, 10) ";
        //数据统计语句
        String countSql = " SELECT COUNT(*) FROM tb_xa_fanliorder orders LEFT JOIN tb_xa_fanlibusiness buss ON orders.bus_id = buss.id\n" +
                "        WHERE 1 = 1 AND buss.status <> 3 " + sqlWhere + " GROUP BY left(fali_time, 10) ";
        //查询的列表集合
        List<Object[]> objs = this.queryParams(sql,  pageable.getPageNumber()*pageable.getPageSize() , pageable.getPageSize(), null);
        List<FanliOrderVo.FanliStatistics> vos=new ArrayList<>();
        for (Object[] obj : objs) {
            FanliOrderVo.FanliStatistics vo = new FanliOrderVo.FanliStatistics();
            vo.setBusId(SqlResultUtil.getSqlResultLong(obj[0]));
            vo.setBusinessName(SqlResultUtil.getSqlResultString(obj[1]));
            vo.setMonth(SqlResultUtil.getSqlResultString(obj[2]));
            vo.setMonthFanliMoney(SqlResultUtil.getSqlResultString(obj[3]));
            vos.add(vo);
        }
        //查询的总条数
        List<Object[]> c = this.queryParams(countSql, null, null, null);
        Page<FanliOrderVo.FanliStatistics> page = new MyPage<>(begin, count, vos,
                XaUtil.isEmpty(c) ? 0 : Integer.valueOf(c.get(0) + ""));
        xr.setObject(page);
        return xr;
    }
}
